home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / mint / utilit~1 / filutl34.zoo / fileutil.34 / src / mountlis.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-02-06  |  14.0 KB  |  503 lines

  1. /* mountlist.c -- return a list of mounted filesystems
  2.    Copyright (C) 1991, 1992 Free Software Foundation, Inc.
  3.  
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 2, or (at your option)
  7.    any later version.
  8.  
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  17.  
  18. #include <stdio.h>
  19. #include <sys/types.h>
  20. #include "mountlist.h"
  21.  
  22. #ifdef STDC_HEADERS
  23. #include <stdlib.h>
  24. #else
  25. void free ();
  26. #endif
  27. #if defined(USG) || defined(STDC_HEADERS)
  28. #include <string.h>
  29. #else
  30. #include <strings.h>
  31. #endif
  32.  
  33. char *strstr ();
  34. char *xmalloc ();
  35. char *xrealloc ();
  36. char *xstrdup ();
  37. void error ();
  38.  
  39. #ifdef MOUNTED_GETMNTENT1       /* 4.3BSD, SunOS, HP-UX, Dynix, Irix.  */
  40. #include <mntent.h>
  41. #if !defined(MOUNTED)
  42. #  if defined(MNT_MNTTAB)       /* HP-UX.  */
  43. #    define MOUNTED MNT_MNTTAB
  44. #  endif
  45. #  if defined(MNTTABNAME)       /* Dynix.  */
  46. #    define MOUNTED MNTTABNAME
  47. #  endif
  48. #endif
  49. #endif
  50.  
  51. #ifdef MOUNTED_GETMNTINFO       /* 4.4BSD.  */
  52. #include <sys/mount.h>
  53. #endif
  54.  
  55. #ifdef MOUNTED_GETMNT           /* Ultrix.  */
  56. #include <sys/param.h>
  57. #include <sys/mount.h>
  58. #include <sys/fs_types.h>
  59. #endif
  60.  
  61. #ifdef MOUNTED_FREAD            /* SVR2.  */
  62. #include <mnttab.h>
  63. #endif
  64.  
  65. #ifdef MOUNTED_FREAD_FSTYP      /* SVR3.  */
  66. #include <mnttab.h>
  67. #include <sys/fstyp.h>
  68. #include <sys/statfs.h>
  69. #endif
  70.  
  71. #ifdef MOUNTED_GETMNTENT2       /* SVR4.  */
  72. #include <sys/mnttab.h>
  73. #endif
  74.  
  75. #ifdef MOUNTED_VMOUNT           /* AIX.  */
  76. #include <fshelp.h>
  77. #include <sys/vfs.h>
  78. #endif
  79.  
  80. #ifdef MOUNTED_GETMNTENT1       /* 4.3BSD, SunOS, HP-UX, Dynix, Irix.  */
  81. /* Return the value of the hexadecimal number represented by CP.
  82.    No prefix (like '0x') or suffix (like 'h') is expected to be
  83.    part of CP. */
  84.  
  85. static int
  86. xatoi (cp)
  87.      char *cp;
  88. {
  89.   int val;
  90.   
  91.   val = 0;
  92.   while (*cp)
  93.     {
  94.       if (*cp >= 'a' && *cp <= 'f')
  95.         val = val * 16 + *cp - 'a' + 10;
  96.       else if (*cp >= 'A' && *cp <= 'F')
  97.         val = val * 16 + *cp - 'A' + 10;
  98.       else if (*cp >= '0' && *cp <= '9')
  99.         val = val * 16 + *cp - '0';
  100.       else
  101.         break;
  102.       cp++;
  103.     }
  104.   return val;
  105. }
  106. #endif /* MOUNTED_GETMNTENT1.  */
  107.  
  108. #ifdef MOUNTED_GETMNTINFO       /* 4.4BSD.  */
  109. static char *
  110. fstype_to_string (t)
  111.      short t;
  112. {
  113.   switch (t)
  114.     {
  115.     case MOUNT_UFS:
  116.       return "ufs";
  117.     case MOUNT_NFS:
  118.       return "nfs";
  119.     case MOUNT_PC:
  120.       return "pc";
  121. #ifdef MOUNT_MFS
  122.     case MOUNT_MFS:
  123.       return "mfs";
  124. #endif
  125. #ifdef MOUNT_LO
  126.     case MOUNT_LO:
  127.       return "lo";
  128. #endif
  129. #ifdef MOUNT_TFS
  130.     case MOUNT_TFS:
  131.       return "tfs";
  132. #endif
  133. #ifdef MOUNT_TMP
  134.     case MOUNT_TMP:
  135.       return "tmp";
  136. #endif
  137.     default:
  138.       return "?";
  139.     }
  140. }
  141. #endif /* MOUNTED_GETMNTINFO */
  142.  
  143. #ifdef MOUNTED_VMOUNT           /* AIX.  */
  144. static char *
  145. fstype_to_string (t)
  146.      int t;
  147. {
  148.   struct vfs_ent *e;
  149.  
  150.   e = getvfsbytype (t);
  151.   if (!e || !e->vfsent_name)
  152.     return "none";
  153.   else
  154.     return e->vfsent_name;
  155. }
  156. #endif /* MOUNTED_VMOUNT */
  157.  
  158. /* Return a list of the currently mounted filesystems, or NULL on error.
  159.    Add each entry to the tail of the list so that they stay in order.
  160.    If NEED_FS_TYPE is nonzero, ensure that the filesystem type fields in
  161.    the returned list are valid.  Otherwise, they might not be.
  162.    If ALL_FS is zero, do not return entries for filesystems that
  163.    are automounter (dummy) entries.  */
  164.    
  165. #ifdef __MINT__
  166. #include <dirent.h>
  167. #include <stat.h>
  168. #include <osbind.h>
  169. extern int __mint;
  170. #endif
  171.  
  172. struct mount_entry *
  173. read_filesystem_list (need_fs_type, all_fs)
  174.      int need_fs_type, all_fs;
  175. {
  176.   struct mount_entry *mount_list;
  177.   struct mount_entry *me;
  178.   struct mount_entry *mtail;
  179.  
  180.   /* Start the list off with a dummy entry. */
  181.   me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  182.   me->me_next = NULL;
  183.   mount_list = mtail = me;
  184.  
  185. /* The following routine was taken from an earlier port */
  186. /* of the fsutils (3.3) by somebody else (? ERS ?).     */
  187. /* It was adapted by HPP to show all filesystems on U:  */
  188. #ifdef __MINT__                 /* MiNT on Atari ST */
  189.   {
  190.     static char ubuf[128] = "u:/";
  191.     DIR *udrv;
  192.     struct dirent *next;
  193.     struct stat statbuf;
  194.     long drvmap, ssp;
  195.     int i;
  196.     int offset;
  197.     struct mount_entry *him;
  198.  
  199.     offset = (Dgetdrv() == 'U'-'A') ? 2 : 0;
  200.     ssp = Super(0L);
  201.     drvmap = *((long *)0x4c2);  /* get which drives are attached */
  202.     if ((*(short *)0x4a6) != 2)
  203.       drvmap &= ~2;             /* drive B: isn't really there */
  204.     Super(ssp);
  205.  
  206.     for (i = 0; i < 32; i++)
  207.     {
  208.       if (drvmap & (1L << i))
  209.       {
  210.         me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  211.         me->me_devname = xstrdup("a:");
  212.         me->me_devname[0] = 'a'+i;
  213.         me->me_mountdir = xstrdup(ubuf);
  214.         me->me_mountdir[0] = me->me_devname[0];
  215.         me->me_dev = i;
  216.         me->me_next = NULL;
  217.         me->me_type = xstrdup( (i < 16) ? "tos" : "pseudo" );
  218.         mtail->me_next = me;
  219.         mtail = me;
  220.       }
  221.     }
  222.     udrv = opendir(ubuf);
  223.     if (udrv)
  224.     {
  225.       while (next = readdir(udrv))
  226.       {
  227.         strcpy(ubuf+3, next->d_name);
  228.         lstat(ubuf, &statbuf);
  229.         if ( (statbuf.st_mode & S_IFMT) == S_IFDIR )
  230.         {
  231.           int replaced = 0;
  232.  
  233.           for (him = mount_list->me_next; him; him = him->me_next)
  234.           {
  235.             if (him->me_devname[0] - 'a' == statbuf.st_dev)
  236.             {
  237.               replaced = 1;
  238.               free(him->me_mountdir);
  239.               him->me_mountdir = xstrdup(ubuf+offset);
  240.               break;
  241.             }
  242.           }
  243.  
  244.           /* Show all subdirs of U: that are not physical drives */
  245.           /* as U:-mounted filesystems. This shows U:\PROC etc.  */
  246.           /* Only do this if MiNT 0.99 or higher is running.     */
  247.           /* (Since Dfree() changed in MiNT 0.97).               */
  248.           if (!replaced && (__mint >= 99) &&
  249.               (statbuf.st_dev >= 32)) /* Pseudodrive */
  250.           {
  251.             char *ptr;
  252.  
  253.             me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  254.             /* mountdir is /xxx (/proc, for instance */
  255.             me->me_mountdir = xstrdup(ubuf+offset);
  256.             /* devname is filesys-name (procfs, for instance). */
  257.             /* this is constructed by catting 'fs' after the dirname */
  258.             ptr = ubuf+offset;
  259.             while (*ptr != 0x00)
  260.               ptr += 1;
  261.             *ptr++ = 'f';
  262.             *ptr++ = 's';
  263.             *ptr++ = ':';
  264.             *ptr = 0x00;
  265.             me->me_devname = xstrdup(ubuf+offset+1);
  266.             me->me_dev = statbuf.st_dev;
  267.             me->me_next = NULL;
  268.             me->me_type = xstrdup( "pseudo" );
  269.             mtail->me_next = me;
  270.             mtail = me;
  271.           }
  272.         } /* End of if (directory in U:) */
  273.       } /* End of while (not end of U:) */
  274.     }
  275.   }
  276. #endif /* __MINT__ */
  277.  
  278. #ifdef MOUNTED_GETMNTENT1       /* 4.3BSD, SunOS, HP-UX, Dynix, Irix.  */
  279.   {
  280.     struct mntent *mnt;
  281.     char *table = MOUNTED;
  282.     FILE *fp;
  283.     char *devopt;
  284.  
  285.     fp = setmntent (table, "r");
  286.     if (fp == NULL)
  287.       return NULL;
  288.  
  289.     while ((mnt = getmntent (fp)))
  290.       {
  291.         if (!all_fs && (!strcmp (mnt->mnt_type, "ignore")
  292.                         || !strcmp (mnt->mnt_type, "auto")))
  293.           continue;
  294.  
  295.         me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  296.         me->me_devname = xstrdup (mnt->mnt_fsname);
  297.         me->me_mountdir = xstrdup (mnt->mnt_dir);
  298.         me->me_type = xstrdup (mnt->mnt_type);
  299.         devopt = strstr (mnt->mnt_opts, "dev=");
  300.         if (devopt)
  301.           {
  302.             if (devopt[4] == '0' && (devopt[5] == 'x' || devopt[5] == 'X'))
  303.               me->me_dev = xatoi (devopt + 6);
  304.             else
  305.               me->me_dev = xatoi (devopt + 4);
  306.           }
  307.         else
  308.           me->me_dev = -1;      /* Magic; means not known yet. */
  309.         me->me_next = NULL;
  310.  
  311.         /* Add to the linked list. */
  312.         mtail->me_next = me;
  313.         mtail = me;
  314.       }
  315.  
  316.     if (endmntent (fp) == 0)
  317.       return NULL;
  318.   }
  319. #endif /* MOUNTED_GETMNTENT1. */
  320.  
  321. #ifdef MOUNTED_GETMNTINFO       /* 4.4BSD.  */
  322.   {
  323.     struct statfs *fsp;
  324.     int entries;
  325.  
  326.     entries = getmntinfo (&fsp, MNT_NOWAIT);
  327.     if (entries < 0)
  328.       return NULL;
  329.     while (entries-- > 0)
  330.       {
  331.         me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  332.         me->me_devname = xstrdup (fsp->f_mntfromname);
  333.         me->me_mountdir = xstrdup (fsp->f_mntonname);
  334.         me->me_type = fstype_to_string (fsp->f_type);
  335.         me->me_dev = -1;        /* Magic; means not known yet. */
  336.         me->me_next = NULL;
  337.  
  338.         /* Add to the linked list. */
  339.         mtail->me_next = me;
  340.         mtail = me;
  341.         fsp++;
  342.       }
  343.   }
  344. #endif /* MOUNTED_GETMNTINFO */
  345.  
  346. #ifdef MOUNTED_GETMNT           /* Ultrix.  */
  347.   {
  348.     int offset = 0;
  349.     int val;
  350.     struct fs_data fsd;
  351.  
  352.     while ((val = getmnt (&offset, &fsd, sizeof (fsd), NOSTAT_MANY,
  353.                           (char *) 0)) > 0)
  354.       {
  355.         me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  356.         me->me_devname = xstrdup (fsd.fd_req.devname);
  357.         me->me_mountdir = xstrdup (fsd.fd_req.path);
  358.         me->me_type = gt_names[fsd.fd_req.fstype];
  359.         me->me_dev = fsd.fd_req.dev;
  360.         me->me_next = NULL;
  361.  
  362.         /* Add to the linked list. */
  363.         mtail->me_next = me;
  364.         mtail = me;
  365.       }
  366.     if (val < 0)
  367.       return NULL;
  368.   }
  369. #endif /* MOUNTED_GETMNT. */
  370.  
  371. #if defined (MOUNTED_FREAD) || defined (MOUNTED_FREAD_FSTYP) /* SVR[23].  */
  372.   {
  373.     struct mnttab mnt;
  374.     char *table = "/etc/mnttab";
  375.     FILE *fp;
  376.  
  377.     fp = fopen (table, "r");
  378.     if (fp == NULL)
  379.       return NULL;
  380.  
  381.     while (fread (&mnt, sizeof mnt, 1, fp) > 0)
  382.       {
  383.         me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  384. #ifdef GETFSTYP                 /* SVR3.  */
  385.         me->me_devname = xstrdup (mnt.mt_dev);
  386. #else
  387.         me->me_devname = xmalloc (strlen (mnt.mt_dev) + 6);
  388.         strcpy (me->me_devname, "/dev/");
  389.         strcpy (me->me_devname + 5, mnt.mt_dev);
  390. #endif
  391.         me->me_mountdir = xstrdup (mnt.mt_filsys);
  392.         me->me_dev = -1;        /* Magic; means not known yet. */
  393.         me->me_type = "";
  394. #ifdef GETFSTYP                 /* SVR3.  */
  395.         if (need_fs_type)
  396.           {
  397.             struct statfs fsd;
  398.             char typebuf[FSTYPSZ];
  399.  
  400.             if (statfs (me->me_mountdir, &fsd, sizeof fsd, 0) != -1
  401.                 && sysfs (GETFSTYP, fsd.f_fstyp, typebuf) != -1)
  402.               me->me_type = xstrdup (typebuf);
  403.           }
  404. #endif
  405.         me->me_next = NULL;
  406.  
  407.         /* Add to the linked list. */
  408.         mtail->me_next = me;
  409.         mtail = me;
  410.       }
  411.  
  412.     if (fclose (fp) == EOF)
  413.       return NULL;
  414.   }
  415. #endif /* MOUNTED_FREAD || MOUNTED_FREAD_FSTYP.  */
  416.  
  417. #ifdef MOUNTED_GETMNTENT2       /* SVR4.  */
  418.   {
  419.     struct mnttab mnt;
  420.     char *table = MNTTAB;
  421.     FILE *fp;
  422.     int ret;
  423.  
  424.     fp = fopen (table, "r");
  425.     if (fp == NULL)
  426.       return NULL;
  427.  
  428.     while ((ret = getmntent (fp, &mnt)) == 0)
  429.       {
  430.         me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  431.         me->me_devname = xstrdup (mnt.mnt_special);
  432.         me->me_mountdir = xstrdup (mnt.mnt_mountp);
  433.         me->me_type = xstrdup (mnt.mnt_fstype);
  434.         me->me_dev = -1;        /* Magic; means not known yet. */
  435.         me->me_next = NULL;
  436.  
  437.         /* Add to the linked list. */
  438.         mtail->me_next = me;
  439.         mtail = me;
  440.       }
  441.  
  442.     if (ret > 0)
  443.       return NULL;
  444.    if (fclose (fp) == EOF)
  445.       return NULL;
  446.   }
  447. #endif /* MOUNTED_GETMNTENT2.  */
  448.  
  449. #ifdef MOUNTED_VMOUNT           /* AIX.  */
  450.   {
  451.     int bufsize;
  452.     char *entries, *thisent;
  453.     struct vmount *vmp;
  454.  
  455.     /* Ask how many bytes to allocate for the mounted filesystem info.  */
  456.     mntctl (MCTL_QUERY, sizeof bufsize, (struct vmount *) &bufsize);
  457.     entries = xmalloc (bufsize);
  458.  
  459.     /* Get the list of mounted filesystems.  */
  460.     mntctl (MCTL_QUERY, bufsize, (struct vmount *) entries);
  461.  
  462.     for (thisent = entries; thisent < entries + bufsize;
  463.          thisent += vmp->vmt_length)
  464.       {
  465.         vmp = (struct vmount *) thisent;
  466.         me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
  467.         if (vmp->vmt_flags & MNT_REMOTE)
  468.           {
  469.             char *host, *path;
  470.  
  471.             /* Prepend the remote pathname.  */
  472.             host = thisent + vmp->vmt_data[VMT_HOSTNAME].vmt_off;
  473.             path = thisent + vmp->vmt_data[VMT_OBJECT].vmt_off;
  474.             me->me_devname = xmalloc (strlen (host) + strlen (path) + 2);
  475.             strcpy (me->me_devname, host);
  476.             strcat (me->me_devname, ":");
  477.             strcat (me->me_devname, path);
  478.           }
  479.         else
  480.           {
  481.             me->me_devname = xstrdup (thisent + 
  482.                                       vmp->vmt_data[VMT_OBJECT].vmt_off);
  483.           }
  484.         me->me_mountdir = xstrdup (thisent + vmp->vmt_data[VMT_STUB].vmt_off);
  485.         me->me_type = xstrdup (fstype_to_string (vmp->vmt_gfstype));
  486.         me->me_dev = -1;        /* vmt_fsid might be the info we want.  */
  487.         me->me_next = NULL;
  488.  
  489.         /* Add to the linked list. */
  490.         mtail->me_next = me;
  491.         mtail = me;
  492.       }
  493.     free (entries);
  494.   }
  495. #endif /* MOUNTED_VMOUNT. */
  496.  
  497.   /* Free the dummy head. */
  498.   me = mount_list;
  499.   mount_list = mount_list->me_next;
  500.   free (me);
  501.   return mount_list;
  502. }
  503.